package com.alinesno.cloud.base.notice.wechat;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;

import javax.lang.exception.RpcServiceRuntimeException;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.alinesno.cloud.base.notice.dto.WechatMessageDto;
import com.alinesno.cloud.base.notice.entity.WechatNoticeEntity;
import com.alinesno.cloud.base.notice.repository.WechatNoticeRepository;

import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;

/**
 * 微信配置
 * 
 * @author WeiXiaoJin
 * @sine 2018年8月5日 下午9:37:25
 */
@Service
public class WechatNoticeServiceImpl implements IWechatNoticeService {

	private static final Logger log = LoggerFactory.getLogger(WechatNoticeServiceImpl.class);

	private static WxMpInMemoryConfigStorage config = new WxMpInMemoryConfigStorage();
	public static final Object WX_OAUTH2_TOKEN = "wx_auth2_token";
	public static Map<String, String> tokenMap = new HashMap<String, String>();

	@Value("${wechat.app.id}")
	private String appId;

	@Value("${wechat.app.secret}")
	private String appSecret;

	@Value("${wechat.token}")
	private String token;

	@Value("${wechat.aes-key}")
	private String aesKey;

	private static final String TEXT_COLDE = "#333333";

	private WxMpService wxService = null;

	@Autowired
	private WechatNoticeRepository wechatNoticeRepository;

	/**
	 * 基础配置
	 */
	public WechatNoticeServiceImpl() {
	}

	public WxMpService getInstance() {
		if (wxService == null) {
			wxService = new WxMpServiceImpl();
			config.setAppId(appId); // 设置微信公众号的appid
			config.setSecret(appSecret); // 设置微信公众号的app corpSecret
			config.setToken(token); // 设置微信公众号的token
			config.setAesKey(aesKey); // 设置微信公众号的EncodingAESKey
			wxService.setWxMpConfigStorage(config);
		}
		return wxService;
	}

	/**
	 * 新订单通知<br/>
	 * {{first.DATA}}<br/>
	 * 订单编号：{{keyword1.DATA}}<br/>
	 * 客户昵称：{{keyword2.DATA}}<br/>
	 * 订单价格：{{keyword3.DATA}}<br/>
	 * 订单标题：{{keyword4.DATA}}<br/>
	 * 订单截止时间：{{keyword5.DATA}}<br/>
	 * {{remark.DATA}}
	 */
	@Override
	public WxMpTemplateMessage sendMessage(Map<String, Object> map, WechatMessageDto m) {

		Assert.notNull(m, "消息实体信息不能为空.");
		Assert.isTrue(map.size() > 0, "实体信息不能为空.");
		Assert.hasLength(m.getOpenId(), "发送用户不能为空.");
		Assert.hasLength(m.getTemplateId(), "发送模板ID不能为空.");

		WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
				.toUser(m.getOpenId())
				.templateId(m.getTemplateId())
				.url(m.getUrl())
				.build();

		for (String k : map.keySet()) {
			templateMessage.addData(new WxMpTemplateData(k, map.get(k) + "", TEXT_COLDE));
		}

		String tip = null;
		try {
			tip = getInstance().getTemplateMsgService().sendTemplateMsg(templateMessage);
			this.saveSendTemplate(tip, "message-success", templateMessage.getData().toString());

			log.debug("推送消息[{}]至[{}]成功", ToStringBuilder.reflectionToString(templateMessage), m.getOpenId());
		} catch (WxErrorException e) {

			this.saveSendTemplate(tip, "message-fail", templateMessage.getData().toString(), e.getMessage());
			log.debug("推送消息[{}]至[{}]失败", ToStringBuilder.reflectionToString(templateMessage), m.getOpenId());
			
			throw new RpcServiceRuntimeException("消息推送["+m.getOpenId()+"]失败:"+e.getMessage()) ; 
		}

		return templateMessage;
	}

	private void saveSendTemplate(String tip, String string, String id) {
		this.saveSendTemplate(tip, string, id, null);
	}

	/**
	 * 保存发送结果
	 * 
	 * @param tip
	 * @param prop
	 * @param userId
	 */
	private void saveSendTemplate(String tip, String prop, String userId, String errorMsg) {
		WechatNoticeEntity t = new WechatNoticeEntity();
		t.setTemplateContent(tip);
		t.setErrorMessage(errorMsg);
		t.setAddTime(new Timestamp(System.currentTimeMillis()));
		t.setFieldProp(prop);
		t.setUserId(userId);
		wechatNoticeRepository.save(t);
	}

}
